import java.util.Base64
import java.util.ArrayList
import java.util.HashMap
import java.util.Map
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
import groovy.json.JsonOutput

//*************************************************************************************************************************//
//**                                               远控逻辑处理                                                            **//
//*************************************************************************************************************************//

def testJobsInfo(env, buildObject){
    String token = "remoteAutoTest"
    // Gpos模型工程测试构建job url 需要维护
    String gposModelTestBuildUrl = "http://autotest.uat.sunmi.com/view/MAX/job/max-roc-scenario-${env}/build?token=${token}" //调试用

    
    def testJobsMap = [:]
    testJobsMap.put("Tbank_Gpos", gposModelTestBuildUrl)



    def testJobResult = testJobsMap.get(buildObject)
    return testJobResult
}


// 获取构建对象Info
def getExecutableJobs(buildInfo){
    //{testBuildEnv=test, testBuildType=model, testBuildObject=Tbank_Gpos, testBuildBranch=, testOssUrl=}
    String testBuildEnv = buildInfo.get("testBuildEnv")
    String testBuildType = buildInfo.get("testBuildType")
    String testBuildObject = buildInfo.get("testBuildObject")
    String testBuildBranch = buildInfo.get("testBuildBranch")
    
    def testJobsInfo = testJobsInfo(testBuildEnv, testBuildObject)
    
    return testJobsInfo
}


// 远程构建autotest Jenkins上的job
def remoteBuildAutoTestJob(command){
    try{
        // sh command
        def curlResult = sh(returnStdout: true, script: "${command}")
        def exitCode = sh(returnStatus: true, script: "${command}")
        env.EXIT_CODE = exitCode.toString()
        def stdout = curlResult.trim()
        if (stdout.contains("404")) {
            error "command is Wrong! \n -- command : ${command}"
        }
        else {
            if (curlResult == null || stdout.isEmpty()) {
                if (exitCode == 0) {
                    echo "command : ${command} is finished"
                } else {
                    echo "command : ${command}"
                    error "command is Wrong! exitCode = ${exitCode}. Stopping the build."
                }
            }else{
                echo "curlResult : ${curlResult} or stdout is Error"
                error "command is Wrong! exitCode = ${exitCode}. Stopping the build."
            }
        }
    }
    catch(Exception e){
            def exitCode = env.EXIT_CODE
            echo "command : ${command}"
            error "commandExcption : Failed to execute the command: ${e.getMessage()}, exitCode = '${exitCode}'"
    }
}


//*************************************************************************************************************************//
//**                                               参数逻辑处理                                                            **//
//*************************************************************************************************************************//

// projectCode_projectAlias : 哪个租户下的哪个工程
def tenantProductReflection(){
    /**
    reflectionName: 谁的什么应用，例如：TBANK_GPOS
    reflectionInfo: 应用下的什么工程 例如：???
    **/
    def reflectionName = [:]

    // Gpos 模型
    // Gpos Web工程
    reflectionName.put("PRJ24052403al236zg7vx26ulnq4qsr6ku_demoWeb", "Tbank_Gpos") // 调试用
    reflectionName.put("_", "") // 调试用
    // Gpos 应用
    // Gpos_m 应用
    // 掌银 ???
    
    return reflectionName
}

// 环境枚举
def stageEnumeration(){
    String[] stageTypes = ["test", "pre", "prod"]
    List<String> stageTypesList = Arrays.asList(stageTypes)
    return stageTypesList
}

// 分支枚举
def branchEnumeration(){
    String[] branchTypes = ["hotfix", "feature"]
    List<String> branchTypesList = Arrays.asList(branchTypes)
    return branchTypesList
}

// 工程类型判断
def assertBuildType(buildType){
    if(!"web".equals(buildType)){
        return false
    }
    return true
}

// jsonBody解析
def jsonBodyAnalyze(jsonBody){
    def emptyJson = [:]
    def jsonSlurper = new JsonSlurper()
    def jsonObj = jsonSlurper.parseText(jsonBody)
    
    // 公共参数校验
    boolean allTrue = true
    boolean projectNameIsTrue = jsonObj.containsKey("projectName")
    boolean projectAliasIsTrue = jsonObj.containsKey("projectAlias")
    boolean projectCodeIsTrue = jsonObj.containsKey("projectCode")
    boolean stageIsTrue = jsonObj.containsKey("stage")
    boolean iterationCodeIsTrue = jsonObj.containsKey("iterationCode")
    boolean iterationTypeIsTrue = jsonObj.containsKey("iterationType")
    boolean projectSubTypeIsTrue = jsonObj.containsKey("projectSubType")
    // boolean serviceInfoIsTrue = jsonObj.containsKey("serviceInfo")
    // boolean outcomeUrlIsTrue = true
    
    [projectCodeIsTrue, projectNameIsTrue, projectAliasIsTrue, stageIsTrue, iterationCodeIsTrue, iterationTypeIsTrue, projectSubTypeIsTrue].each { item ->
        if (!item) {allTrue = false}
    }
    
    if (!allTrue) {
        error "params is wrong! \n params : ${jsonBody}"
    }
    if(!assertBuildType(jsonObj.get("projectSubType"))){
        error "projectSubType is not \"Web\" "
    }
    jsonObj["projectCode_projectAlias"] = jsonObj.get("projectCode") + "_" + jsonObj.get("projectAlias")
    return jsonObj
}

// 远控构建条件
def getRemoteBuildConditions(jsonBodyAnalyze_jsonBody){
    def emptyJson = [:]
    
    if (jsonBodyAnalyze_jsonBody.isEmpty()){
        error "jsonBody is Empty"
    }
    
    List<String> stageEnumeration = stageEnumeration()
    String buildType = jsonBodyAnalyze_jsonBody.get("projectSubType")
    String buildEnv = jsonBodyAnalyze_jsonBody.get("stage")
    String projectCode_projectAlias = jsonBodyAnalyze_jsonBody.get("projectCode_projectAlias")
    if (!stageEnumeration.contains(buildEnv)){
        error "buildEnv Enumeration is Error"
    }
    def tenantProductReflection = tenantProductReflection()
    String testBuildObject = tenantProductReflection.get(projectCode_projectAlias)
    if (testBuildObject == null || testBuildObject.isEmpty()){
        error "tenantProductReflection 配置缺少或错误，请人工介入维护"
    }

    def buildConditions = [:]
    buildConditions.put("testBuildEnv", buildEnv)
    buildConditions.put("testBuildType", buildType)
    buildConditions.put("testBuildObject", testBuildObject)
    buildConditions.put("testBuildBranch", "")
    buildConditions.put("testOssUrl", "")
    
    switch(buildType) {
        case "web":
            // do something
            break
        case "app":
            // do something
            break
        case "h5":
            // do something
            break
        case "component":
            // do something
            break
        case "sdk":
            // do something
            break
        case "model":
            // do something
            break
        case "component_app":
            // do something
            break
        default:
            error "buildType is Error"
            return emptyJson
    }
    
    return buildConditions
}

pipeline {
    agent any

    parameters {
        string (
            name: 'jsonBody',
            description: 'jsonBody',
            defaultValue: ''
        )
    }

    environment {
        jsonBody = "${params.jsonBody}"
        host = "autotest.uat.sunmi.com"
        remoteTestJobToken = "remoteAutoTest"
    }

    stages {
        stage ('Init') {
            steps {
                withCredentials([
                    string(variable: 'remoteAutoTestName', credentialsId: 'remoteAutoTestName'),
                    string(variable: 'remoteAutoTestUserToken', credentialsId: 'remoteAutoTestUserToken')
                ]) {
                    script {
                        username = "${env.remoteAutoTestName}"
                        userToken = "${env.remoteAutoTestUserToken}"
                        env.authorization2Base64 = Base64.getEncoder().encodeToString("${username}:${userToken}".getBytes())
                        }
                    }
                    echo "jsonBody 参数接收 : ${env.jsonBody} \n"
                }
            }
        stage ('ParameterAnalysis') {
            steps {
                script {
                    def buildInfo = [:]
                    def jsonBodyExt = jsonBodyAnalyze(env.jsonBody)
                    buildInfo = getRemoteBuildConditions(jsonBodyExt)
                    if(buildInfo.isEmpty()){
                        error "buildInfo is Empty"
                    }
                    String buildInfo2Str = JsonOutput.toJson(buildInfo)
                    env.buildInfo = buildInfo2Str
                }
            }
        }
        stage ('DistributeHandle') {
            steps {
                script {
                    def jsonSlurper = new JsonSlurper()
                    def buildInfo = jsonSlurper.parseText(env.buildInfo)
                    String getExecutableJobs = getExecutableJobs(buildInfo)
                    env.testBuildUrl = getExecutableJobs
                    echo "testBuildUrl : ${env.testBuildUrl}"
                }
            }
        }
        stage ('DistributeBuild') {
            steps {
                script {
                    String command = "curl -s -X GET -H 'Authorization: Basic ${env.authorization2Base64}' '${env.testBuildUrl}'"
                    remoteBuildAutoTestJob(command)
                }
            }
        }
    }
}
